package edu.gatech.mobile.scene.provider.impl;

import java.util.ArrayList;
import java.util.List;

import org.opencv.core.CvType;
import org.opencv.core.Mat;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import edu.gatech.mobile.scene.AppConstants;
import edu.gatech.mobile.scene.model.ColorHistogram;

/**
 * Helper class for color histogram data base table
 * @author Jing
 *
 */
public class ColorHistogramDBImpl {
	private Context mContext;

	public ColorHistogramDBImpl(Context context) {
		mContext = context;
	}
	
	/**
	 * storing histogram into the database.
	 * @param histogram histogram to be stored into the database.
	 */
	public void putHistogram(ColorHistogram histogram){
		ContentResolver resolver = mContext.getContentResolver();
		List<ContentValues> values = getQueryValues(histogram);
		for(ContentValues value : values){
			resolver.insert(ColorHistogramTable.CONTENT_URI, value);
		}
	}
	
	/**
	 * retrieve the histogram for the given maskId.
	 * @param maskId used to retrieve the correct histogram.
	 * @return the histogram associated with maskId.
	 */
	public ColorHistogram getHistogramForMask(long maskId){
		ContentResolver resolver = mContext.getContentResolver();
		String where = ColorHistogramTable.MASK_ID + " = "+maskId;
		Cursor cursor =resolver.query(ColorHistogramTable.CONTENT_URI, null, where, null, null);
		ColorHistogram histograms = fillFromCursor(cursor);
		return histograms;
	}
	
	/**
	 * Construct a ColorHistogram by getting the values from the current line the cursor points to.
	 * @param cursor the open database cursor.
	 * @return ColorHistogram object the cursor points to.
	 */
	private ColorHistogram fillFromCursor(Cursor cursor) {
		ColorHistogram hist = new ColorHistogram(); 
		List<Mat> histograms = new ArrayList<Mat>();
		while (cursor != null && cursor.getCount() > 0 && !cursor.isLast()){
			cursor.moveToNext();
			if(hist.getTime() == null){
				hist.setTime(cursor.getLong(cursor.getColumnIndex(ColorHistogramTable.TIME_POSTED)));
			}
			if(hist.getMaskId() == null){
				hist.setTime(cursor.getLong(cursor.getColumnIndex(ColorHistogramTable.MASK_ID)));
			}
			Mat histogram = new Mat(AppConstants.COLOR_HISTOMGRAM_BIN_SIZE, 1, CvType.CV_32FC1);
			for(int i=0; i<AppConstants.COLOR_HISTOMGRAM_BIN_SIZE; i++){
				float[] value = {cursor.getFloat(cursor.getColumnIndex(ColorHistogramTable.HISTOGRAM_VALUE+i))};
				histogram.put(i, 0, value);
			}
			histograms.add(histogram);
		}
		hist.setColorHistogram(histograms);
		return hist;
	}
	
	/**
	 * construct three tables of column name and value table to be put into the database.
	 * @param histogram histogram to be converted to the table
	 * @return three tables(one for each channel)
	 */
	private List<ContentValues> getQueryValues(ColorHistogram histogram) {
		List<ContentValues> values = new ArrayList<ContentValues>();
		for(int channelNum =0; channelNum<histogram.getColorHistogram().size(); channelNum++){
			ContentValues value = new ContentValues();
			Long time;
			if((time=histogram.getTime()) == null){
				time = System.currentTimeMillis();
			}
			Mat hist = histogram.getColorHistogram().get(channelNum);
			value.put(ColorHistogramTable.TIME_POSTED, time);
			value.put(ColorHistogramTable.CHANNEL, channelNum);
			for(int i=0; i<hist.height(); i++){
				float[] data = new float[1];
				hist.get(i, 0, data);
				value.put(ColorHistogramTable.HISTOGRAM_VALUE+i, data[0]);
			}
			value.put(ColorHistogramTable.MASK_ID, histogram.getMaskId());
			values.add(value);
		}
		return values;
	}
}
